package org.mixed.script.modules.db.table;

import lombok.Getter;
import org.mixed.script.annotation.Comment;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class Where {
    private final List<String> tokens = new ArrayList<>();
    @Getter
    private final List<Object> params = new ArrayList<>();
    private final Table table;

    public Where(Table table) {
        this.table = table;
    }

    @Comment("等于`=`,如：`eq('name', name)`")
    public Where eq(@Comment(name = "column", value = "数据库中的列名") String column,
                    @Comment(name = "value", value = "值") Object value) {
        return eq(true, column, value);
    }

    @Comment("条件等于`=`,如：`eq(name != null, 'name', name)`")
    public Where eq(@Comment(name = "condition", value = "判断表达式，当为true时拼接条件") boolean condition,
                    @Comment(name = "column", value = "数据库中的列名") String column,
                    @Comment(name = "value", value = "值") Object value) {
        if (condition) {
            append(column);
            if (value == null) {
                append("is null");
            } else {
                append("= ?", value);
            }
        }
        return this;
    }

    @Comment("`like`,如：`like('name', '%王%')")
    public Where like(@Comment(name = "column", value = "数据库中的列名") String column,
                      @Comment(name = "value", value = "值") Object value) {
        return like(true, column, value);
    }

    @Comment("`like`,如：`like('name', '%王%')")
    public Where like(@Comment(name = "condition", value = "判断表达式，当为true时拼接条件") boolean condition,
                      @Comment(name = "column", value = "数据库中的列名") String column,
                      @Comment(name = "value", value = "值") Object value) {
        return append(condition, column, "like ?", value);
    }

    @Comment("拼接`and`")
    public Where and() {
        append("and");
        return this;
    }

    public void append(String value) {
        tokens.add(value);
    }

    public void append(String sql, Object value) {
        tokens.add(sql);
        params.add(value);
    }

    private Where append(boolean condition, String column, String operator, Object value) {
        if (condition) {
            append(column);
            append(operator, value);
        }
        return this;
    }

    @Comment("执行select查询")
    public List<Map<String, Object>> select() {
        return table.select();
    }

    @Comment("执行selectOne查询")
    public Map<String, Object> selectOne() {
        return table.selectOne();
    }

    public boolean isEmpty() {
        return tokens.isEmpty();
    }

    public String getSql() {
        if (isEmpty()) {
            return "";
        }
        return " where " + String.join(" ", tokens);
    }
}
